import axios from 'axios';
import { SocksProxyAgent } from 'socks-proxy-agent';
import * as https from 'https';
import { configService } from '../utils/config.service';

/**
 * Telegram消息类型枚举
 */
export enum TelegramMessageType {
  TEXT = 'text',
  PHOTO = 'photo',
  DOCUMENT = 'document',
  AUDIO = 'audio',
  VIDEO = 'video',
}

/**
 * 发送消息选项接口
 */
export interface SendMessageOptions {
  parseMode?: 'HTML' | 'Markdown' | 'MarkdownV2'; // 解析模式
  disableWebPagePreview?: boolean;                // 禁用网页预览
  disableNotification?: boolean;                  // 静默发送(不通知)
  replyToMessageId?: number;                      // 回复消息ID
}

/**
 * 发送媒体选项接口
 */
export interface SendMediaOptions extends SendMessageOptions {
  caption?: string;    // 媒体描述文字
}

/**
 * 发送消息响应接口
 */
export interface TelegramResponse {
  ok: boolean;
  result?: any;
  description?: string;
  error_code?: number;
}

/**
 * Telegram Bot服务配置选项
 */
export interface TelegramBotOptions {
  proxy?: string;      // 代理服务器，例如 'socks5://127.0.0.1:7890'
  timeout?: number;    // 请求超时时间(ms)
}

/**
 * Telegram Bot服务类
 * 提供与Telegram Bot API交互的方法
 */
export class TelegramBotService {
  private readonly baseUrl: string;
  private readonly token: string;
  private readonly axiosInstance: any;

  /**
   * 构造函数
   * @param token Telegram Bot Token，如果未提供，将从环境变量中获取
   * @param options 配置选项，包括代理设置
   */
  constructor(token?: string, options: TelegramBotOptions = {}) {
    // 确保dotenv已正确加载
    try {
      require('dotenv').config();
    } catch (e) {
      console.warn('警告: dotenv加载失败，可能环境变量未正确配置');
    }

    this.token = token || process.env.TELEGRAM_BOT_TOKEN || '';

    console.log(`Telegram Bot Token状态: ${this.token ? '已配置' : '未配置'}`);
    if (this.token) {
      console.log(`Token前5个字符: ${this.token.substring(0, 5)}...`);
    }

    if (!this.token) {
      throw new Error('Telegram Bot Token未提供。请在环境变量中设置TELEGRAM_BOT_TOKEN或通过构造函数提供');
    }

    this.baseUrl = `https://api.telegram.org/bot${this.token}`;
    console.log(`Telegram API基础URL: ${this.baseUrl}`);

    // 创建带有代理支持的axios实例
    const axiosConfig: any = {
      timeout: options.timeout || 30000,
      headers: {
        'Content-Type': 'application/json'
      },
      // 允许自签名证书，避免SSL错误
      httpsAgent: new https.Agent({
        rejectUnauthorized: false
      })
    };

    // 统一处理代理配置
    // 优先级: options.proxy > config.yaml > no proxy
    let proxyToUse = options.proxy;
    if (proxyToUse === undefined) {
      const proxyFromConfig = configService.getProxy();
      proxyToUse = proxyFromConfig === null ? undefined : proxyFromConfig;
    }

    // 配置代理
    if (proxyToUse) {
      // 处理SOCKS5代理
      if (proxyToUse.includes('socks5')) {
        const socksAgent = new SocksProxyAgent(proxyToUse);
        axiosConfig.httpsAgent = socksAgent;
        axiosConfig.httpAgent = socksAgent;
        console.log(`已配置SOCKS5代理: ${proxyToUse}`);
      } else {
        // 处理普通HTTP代理
        const proxyParts = proxyToUse.split(':');
        axiosConfig.proxy = {
          host: proxyParts[0],
          port: parseInt(proxyParts[1] || '8080')
        };
        console.log(`已配置HTTP代理: ${proxyToUse}`);
      }
    } else {
      console.log('未使用代理');
    }

    this.axiosInstance = axios.create(axiosConfig);
  }

  /**
   * 发送文本消息
   * @param chatId 聊天ID或用户名
   * @param text 消息文本
   * @param options 发送选项
   * @returns Promise包含发送结果
   */
  async sendMessage(
    chatId: number | string,
    text: string,
    options: SendMessageOptions = {}
  ): Promise<TelegramResponse> {
    try {
      console.log(`发送消息到Telegram: chatId=${chatId}, length=${text.length}`);
      console.log(`使用URL: ${this.baseUrl}/sendMessage`);

      const requestData = {
        chat_id: chatId,
        text,
        parse_mode: options.parseMode,
        disable_web_page_preview: options.disableWebPagePreview,
        disable_notification: options.disableNotification,
        reply_to_message_id: options.replyToMessageId
      };

      console.log(`请求数据: ${JSON.stringify({
        chat_id: chatId,
        text: text.substring(0, 20) + '...',  // 只显示文本开头部分
        parse_mode: options.parseMode,
        other_options: !!options  // 简单显示是否有其他选项
      })}`);

      const response = await this.axiosInstance.post(`${this.baseUrl}/sendMessage`, requestData);

      console.log(`Telegram响应: ${JSON.stringify(response.data)}`);
      return response.data;
    } catch (error: any) {
      console.error('Telegram发送消息失败:', error.message);

      // 详细记录错误信息
      if (error.response) {
        console.error(`HTTP状态码: ${error.response.status}`);
        console.error(`错误详情: ${JSON.stringify(error.response.data || {})}`);
        return {
          ok: false,
          error_code: error.response.status,
          description: error.response.data?.description || error.message
        };
      } else if (error.request) {
        // 请求已发送但没有收到响应
        console.error('没有收到响应，请检查网络连接或代理配置');
      }

      return { ok: false, description: error.message };
    }
  }

  /**
   * 发送照片
   * @param chatId 聊天ID或用户名
   * @param photo 图片URL或文件ID
   * @param options 发送选项
   * @returns Promise包含发送结果
   */
  async sendPhoto(
    chatId: number | string,
    photo: string,
    options: SendMediaOptions = {}
  ): Promise<TelegramResponse> {
    try {
      console.log(`发送图片到Telegram: chatId=${chatId}, photo=${photo}`);
      const response = await this.axiosInstance.post(`${this.baseUrl}/sendPhoto`, {
        chat_id: chatId,
        photo,
        caption: options.caption,
        parse_mode: options.parseMode,
        disable_notification: options.disableNotification,
        reply_to_message_id: options.replyToMessageId
      });

      return response.data;
    } catch (error: any) {
      console.error('Telegram发送照片失败:', error.message);

      if (error.response) {
        return {
          ok: false,
          error_code: error.response.status,
          description: error.response.data?.description || error.message
        };
      }

      return { ok: false, description: error.message };
    }
  }

  /**
   * 发送文档
   * @param chatId 聊天ID或用户名
   * @param document 文档URL或文件ID
   * @param options 发送选项
   * @returns Promise包含发送结果
   */
  async sendDocument(
    chatId: number | string,
    document: string,
    options: SendMediaOptions = {}
  ): Promise<TelegramResponse> {
    try {
      console.log(`发送文档到Telegram: chatId=${chatId}, document=${document}`);
      const response = await this.axiosInstance.post(`${this.baseUrl}/sendDocument`, {
        chat_id: chatId,
        document,
        caption: options.caption,
        parse_mode: options.parseMode,
        disable_notification: options.disableNotification,
        reply_to_message_id: options.replyToMessageId
      });

      return response.data;
    } catch (error: any) {
      console.error('Telegram发送文档失败:', error.message);

      if (error.response) {
        return {
          ok: false,
          error_code: error.response.status,
          description: error.response.data?.description || error.message
        };
      }

      return { ok: false, description: error.message };
    }
  }

  /**
   * 获取机器人信息
   * @returns Promise包含机器人信息
   */
  async getMe(): Promise<TelegramResponse> {
    try {
      console.log('获取Telegram机器人信息');
      console.log(`使用URL: ${this.baseUrl}/getMe`);

      const response = await this.axiosInstance.get(`${this.baseUrl}/getMe`);
      console.log(`Telegram响应: ${JSON.stringify(response.data)}`);
      return response.data;
    } catch (error: any) {
      console.error('获取机器人信息失败:', error.message);

      // 详细记录错误信息
      if (error.response) {
        console.error(`HTTP状态码: ${error.response.status}`);
        console.error(`错误详情: ${JSON.stringify(error.response.data || {})}`);
        return {
          ok: false,
          error_code: error.response.status,
          description: error.response.data?.description || error.message
        };
      } else if (error.request) {
        console.error('没有收到响应，请检查网络连接或代理配置');
      }

      return { ok: false, description: error.message };
    }
  }

  /**
   * 发送交易提醒消息
   * 格式化的交易消息示例
   * @param chatId 聊天ID或用户名
   * @param symbol 交易对符号
   * @param price 价格
   * @param action 操作类型（买入/卖出）
   * @param quantity 数量
   * @returns Promise包含发送结果
   */
  async sendTradeAlert(
    chatId: number | string,
    symbol: string,
    price: number,
    action: 'BUY' | 'SELL',
    quantity: number
  ): Promise<TelegramResponse> {
    const emoji = action === 'BUY' ? '🟢' : '🔴';
    const actionText = action === 'BUY' ? '买入' : '卖出';

    const message = `
${emoji} <b>交易提醒</b> ${emoji}

<b>交易对:</b> ${symbol}
<b>操作:</b> ${actionText}
<b>价格:</b> ${price}
<b>数量:</b> ${quantity}
<b>时间:</b> ${new Date().toLocaleString('zh-CN')}
`;

    return this.sendMessage(chatId, message, { parseMode: 'HTML' });
  }
} 